/* DxfPOLYLINE.java
 *
 * Created on 5 de Dezembro de 2007, 10:02
 * 
 * Modified 08/10/2011, 02:32 PM by Adriano
 * Included the attribute @Override to inherited methods
 */

package importadorDXF;

import java.util.Enumeration;
import mathematics.Point3D;

/**
 * @author rafaelbuck
 * @author Adriano Ferreira 
 */
public class DxfPOLYLINE extends DxfEntity implements DxfEntityCollector
{
    @Override
    public boolean setGroup(short grpNr, float fval)
    {
        switch(grpNr)
        {
        case 10: // '\n'
        case 20: // '\024'
        case 30: // '\036'
            setCoord(basis, grpNr / 10, fval);
            return true;

        case 40: // '('
            startWidth = fval;
            return true;

        case 41: // ')'
            endWidth = fval;
            return true;
        }
        
        return super.setGroup(grpNr, fval);
    }

    @Override
    public boolean setGroup(short grpNr, int ival)
    {
        switch(grpNr)
        {
        case 66: // 'B'
            vertexFlag = ival != 0;
            return true;

        case 70: // 'F'
            type = ival;
            return true;

        case 71: // 'G'
            nrCtrlU = ival;
            return true;

        case 72: // 'H'
            nrCtrlV = ival;
            return true;

        case 73: // 'I'
            nrApproxM = ival;
            return true;

        case 74: // 'J'
            nrApproxN = ival;
            return true;

        case 75: // 'K'
            smooth = ival;
            return true;
        }
        
        return super.setGroup(grpNr, ival);
    }

    public boolean hasLineWidth()
    {
        if(!prepared)
            prepare();
        return hasWidth;
    }

    @Override
    public boolean addEntity(DxfEntity vertex) throws DxfException
    {
        if(vertex instanceof DxfVERTEX)
        {
            vertices.addEntity(vertex);
            return true;
        }
        if(vertex.isTerm() && (vertex instanceof DxfSEQEND))
            return false;
        else
            throw new DxfException("err!VertexAfterPolyline");
    }

    @Override
    public DxfEntityCollector getEntityCollector()
    {
        return vertexFlag ? this : null;
    }

    @Override
    public void convert(DxfConverter converter, DxfFile dxf, Object collector)
    {
        if(!prepared)
            prepare();
        converter.convert(this, dxf, collector);
    }

    public final boolean vertexFollowing()
    {
        return vertexFlag;
    }

    public final Point3D getBasis()
    {
        return basis;
    }

    public final int getType()
    {
        return type;
    }

    public final float getStartWidth()
    {
        return startWidth;
    }

    public final float getEndWidth()
    {
        return endWidth;
    }

    public final int getNrCtrlU()
    {
        return nrCtrlU;
    }

    public final int getNrCtrlV()
    {
        return nrCtrlV;
    }

    public final int getNrApproxM()
    {
        return nrApproxM;
    }

    public final int getNrApproxN()
    {
        return nrApproxN;
    }

    public final int getSmoothType()
    {
        return smooth;
    }

    public final DxfEntitySet getVertices()
    {
        return vertices;
    }

    private void prepare()
    {
        if(!prepared)
        {
            prepared = true;
            DxfVERTEX first = (DxfVERTEX)vertices.getEntity(0);
            if(first.getStartWidth() < 0.0F)
                first.setStartWidth(getStartWidth());
            if(first.getEndWidth() < 0.0F)
                first.setEndWidth(getEndWidth());
            float lastEndWidth = (getType() & 1) == 0 ? 0.0F : ((DxfVERTEX)vertices.getEntity(vertices.getNrOfEntities() - 1)).getEndWidth();
            for(Enumeration e = vertices.getEntities(); e.hasMoreElements();)
            {
                DxfVERTEX v = (DxfVERTEX)e.nextElement();
                float width;
                if((width = v.getStartWidth()) > 0.0F)
                    hasWidth = true;
                else
                if(width < 0.0F)
                    v.setStartWidth(lastEndWidth);
                if((width = v.getEndWidth()) > 0.0F)
                    hasWidth = true;
                else
                if(width < 0.0F)
                    v.setEndWidth(v.getStartWidth());
                if((lastEndWidth = v.getEndWidth()) > 0.0F)
                    hasWidth = true;
            }

        }
    }

    /** Creates a new instance of DxfPOLYLINE */
    public DxfPOLYLINE()
    {
        vertexFlag = true;
        basis = new Point3D();
        vertices = new DxfEntitySet();
        prepared = false;
        hasWidth = false;
    }

    protected boolean vertexFlag;
    protected Point3D basis;
    protected int type;
    protected float startWidth;
    protected float endWidth;
    protected int nrCtrlU;
    protected int nrCtrlV;
    protected int nrApproxM;
    protected int nrApproxN;
    protected int smooth;
    protected DxfEntitySet vertices;
    private boolean prepared;
    private boolean hasWidth;
    public static final int CLOSED = 1;
    public static final int CURVE_FIT = 2;
    public static final int B_SPLINE = 4;
    public static final int THREE_DIM = 8;
    public static final int WEB = 16;
    public static final int WEB_CLOSED = 32;
    public static final int NET = 64;
    public static final int CONT_LTYPE = 128;
    public static final int TWO_DIM = 6;
    public static final int ANY_WEB = 48;
    public static final int NO_SMOOTH = 0;
    public static final int B_SPLINE_2 = 5;
    public static final int B_SPLINE_3 = 6;
    public static final int BEZIER = 8;
}